/*
Remove the comment from line 267 to integrate it with HIP.
*/


#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 
#include <arpa/inet.h>

#include "policy.h"
#include "nm.h"
using namespace std;

int interfaceStatus(char* desInt);

int polModel(char** returnedInterfaces, int appID, int sockfd)
{
/*
Reduced stuff. We do the following.
Parse the file. Check appropriate AppID and the
corresponding list of interfaces.
Split the interfaces and store in a 2D array.
*/
    int result=0;
    int j=0;
    int interfaceIndex=0;
    char* protocol=(char *) malloc (sizeof(char) * 10);
    char* answer=(char *) malloc (sizeof(char) * 10);	
    char** data;// = (char **) malloc (sizeof(char) * 50);
    protocol="hip";	

    //allocate memory for rows
    data = (char**)malloc(100 *sizeof(char*));
    //for each row allocate memory for columns
    for(int i=0; i<100; i++) 
    {
   	*(data+i) = (char*)malloc(3 *sizeof(char));
    }

    	

    char** interfaces;
    interfaces = (char**)malloc(100 *sizeof(char*));
    for(int i=0; i<100; i++)
    {
       *(interfaces+i) = (char*)malloc(3 *sizeof(char));
    }

    ifstream in("tempData.txt"); // input
    if(!in) {
        cout << "Cannot open input file.\n";
        return 0;
    }
    char str[255];
    char parseBuff[255];	

    char ch;
    int chCheck;		
    while(in) {
        in.getline(str, 255); // delim defaults to '\n'
        int appIDSearch=atoi(str);
        if(appIDSearch!=appID)
            continue;
        else
        {
          in.getline(parseBuff, 255); // delim defaults to '\n' 
//	  cout<<"******"<<appID<<endl;
	  int n1=atoi(parseBuff);	// n1 has total number of rules.
	  //cout<<"saw - "<<n1<<endl; 	
	  int* condNo = (int *) malloc (sizeof(int) * n1);	// 1-D array to store the # of conditions.
	  int sum=0;	// Total # of conditions.
	  for(int i=0;i<n1;i++)
	  {
		in.getline(parseBuff, 255); // delim defaults to '\n'
		int x=atoi(parseBuff);
		//cout<<"saw - "<<x<<endl;
		sum+=x;
		condNo[i]=x;
	  }

	  int** bandCost;			// Contains the band cost pair
	  bandCost = (int**)malloc(100 *sizeof(int*));
	  for(int i=0; i<100; i++) 
	  {
   		*(bandCost+i) = (int*)malloc(3 *sizeof(int));
    	  }


	 int** boolCheck;			// Contains the band cost pair	  
   	 boolCheck = (int**)malloc(100 *sizeof(int*));
	 for(int i=0; i<100; i++) 
	 {
   		*(boolCheck+i) = (int*)malloc(3 *sizeof(int));
    	 }	
		
	 int dataIndex=0;
	 for(int k=0;k<sum;k++)			// assigning band cost pair here.
	 {
		in.getline(parseBuff, 255); // delim defaults to '\n'
		int j=0;
		dataIndex=0;
		for(int i=0;i<strlen(parseBuff);i++)
    		{
			if(parseBuff[i]!=' '){
            			data[dataIndex][j]=parseBuff[i];
          			j++;
			}
		        else{
		             data[dataIndex][j]='\0';
		             dataIndex++;
		             j=0;
		        }
    		}
		//cout<<"saw --- "<<data[0]<<" "<<data[1]<<endl;		
		int x=atoi(data[0]);
		bandCost[k][0]=x;
		x=atoi(data[1]);
		bandCost[k][1]=x;
		//cout<<"saw --- "<<bandCost[k][0]<<" "<<bandCost[k][1]<<endl;
		//cout<<"Just worked on ----- "<<parseBuff<<endl;
	 }  




	int condIndex=0;
	in.getline(str, 255); // delim defaults to '\n'
	int bandCostIndex = 0;
        int checker=0;	
	    int scanIndex=0;

	   do{
            int totalCond=condNo[condIndex];
//	    int scanIndex=0;
	    int wordNo=0;
	    int xIndex=0;	
	    //cout<<"totalCond = "<<totalCond<<endl;
            for(int i=0;i<strlen(str);i++)
            {
		int conditionIndex=0;
                if(str[i]!=' '){
                    interfaces[interfaceIndex][j]=str[i];
		    //cout<<"!!! "<<interfaces[interfaceIndex][j];
                    j++;
                }
                else{
                 
                    interfaces[interfaceIndex][j]='\0';
		     //cout<<">>>>> "<<interfaces[interfaceIndex]<<endl;
		    //wordNo++;
		    xIndex=0;

	//	    int obtBand=250;
	//	    int obtCost=4;
		    
		    int obtBand = sine_getBandwidth(interfaces[interfaceIndex]);
		    int obtCost = sine_getCost(interfaces[interfaceIndex]);		


		    int tempScanIndex=scanIndex;
		    int flag=0;	
		    while(conditionIndex<totalCond  && interfaceStatus(interfaces[interfaceIndex]))
		    {
//			cout<<"checking "<<interfaces[interfaceIndex]<<" - "<<tempScanIndex<<" "<<bandCost[tempScanIndex][0]<<" "<<bandCost[tempScanIndex][1]<<" word no "<<wordNo<<endl;
			if((bandCost[tempScanIndex][0]<=obtBand) &&  (bandCost[tempScanIndex][1]>=obtCost))
			{
	//			cout<<"assis true with xindex= "<<xIndex<<" wordno = "<<wordNo<<endl;
//			cout<<interfaces[interfaceIndex]<<" "<<interfaceStatus(interfaces[interfaceIndex])<<endl;	
				boolCheck[xIndex][wordNo]=1;
				xIndex++;	 
				tempScanIndex++;
				conditionIndex++;
			}
			else
			{
				boolCheck[xIndex][wordNo]=0;
				xIndex++;
				conditionIndex++;
				tempScanIndex++;
			}
		    }
		    wordNo++;	
                    interfaceIndex++;
		    if(i==strlen(str)-1)
		    {
			int myflag=10;
			for(int m=0;m<totalCond;m++)
			{
				for(int j=0;j<wordNo;j++)
				{
				//	cout<<"::::"<<boolCheck[m][j]<<"::::"<<m<<" "<<j<<"\n";
//	cout<<"This is int status "<<interfaceStatus(interfaces[interfaceIndex])<<interfaces[interfaceIndex]<<endl;
		if(boolCheck[m][j]!=1)// && interfaceStatus(interfaces[interfaceIndex]))
	{ 
		//cout<<interfaceStatus(interfaces[interfaceIndex])<<"for "<<interfaces[interfaceIndex]<<endl;
		myflag=5;break;
	}
				}
									
				if(myflag==10)
				{
		//			cout<<"checker was 199##############\n";
					checker=199;
	//				cout<<"The answer is with "<<str<<endl;
					answer=str;
					break;
				}
				else
				{
					//interfaceIndex--;
		//			cout<<"came in else\n";
					//memset (interfaces[interfaceIndex-1],0,20);
					//interfaceIndex--;
				}
			}
			
		     }	
                    j=0;
		    //scanIndex+=totalCond;	
                }
		if(checker==199) break;  
            }
            interfaces[interfaceIndex][j]='\0';
	    if(checker==199) break;		
	    in.getline(str, 255); // delim defaults to '\n'
	    condIndex++;	
	  //  cout<<"Took a line\n";
	    scanIndex+=totalCond;
	    ch=str[0];
	    chCheck=ch;
	   }while(chCheck!=13 && chCheck!=0);
	 }    	
		 
	
	//cout<<"Do something with - "<<answer<<endl;


	char** tempInterfaces;
	tempInterfaces = (char**)malloc(100 *sizeof(char*));
	for(int i=0; i<100; i++)
	{
	   *(tempInterfaces+i) = (char*)malloc(3 *sizeof(char));
	}


	int tempJ=0;
	//int dataIndex=0;	
	for(int i=0;i<strlen(answer);i++)
    	{
		if(answer[i]!=' '){
        	tempInterfaces[result][tempJ]=answer[i];
        	tempJ++;
		}
	        else{
	             tempInterfaces[result][tempJ]='\0';
	//	     cout<<tempInterfaces[result]<<endl;
	             result++;
	             tempJ=0;
	        }
    	}
//	cout<<"The number of interface mathces is = "<<result<<endl;
//	cout<<"Sending "<<tempInterfaces[0];
	if(result==0)
		cout<<"Process cannot continue\n";	
	int retCount=0;
                for(int i=0;i<=result-1;i++)
                {
		    if(interfaceStatus(tempInterfaces[i])==1)
		    {
			returnedInterfaces[retCount]=tempInterfaces[i];
			cout<<"Found interface - "<<returnedInterfaces[retCount]<<" matching the policy"<<endl;
			sine_setHipIf(sockfd, returnedInterfaces[retCount]);
		//	return 0;
			break;
			retCount++;
		    }
                }
    }
    in.close();
    //free(answer);	
    return result;
}


int interfaceStatus(char* desInt)
{
	char* buffer=(char *) malloc (sizeof(char) * 10);
	memset (buffer,0,0);
	//buffer = sine_getIfStatus(desInt);
	sine_getIfStatus(desInt, buffer);
	if(!strcmp(buffer, "up"))
		return 1;
    	else
		return 0;
}
